package com.pbd.client;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.maps.client.InfoWindow;
import com.google.gwt.maps.client.InfoWindowContent;
import com.google.gwt.maps.client.MapWidget;
import com.google.gwt.maps.client.event.MarkerDragEndHandler;
import com.google.gwt.maps.client.geocode.Geocoder;
import com.google.gwt.maps.client.geocode.LatLngCallback;
import com.google.gwt.maps.client.geom.LatLng;
import com.google.gwt.maps.client.geom.LatLngBounds;
import com.google.gwt.maps.client.geom.Point;
import com.google.gwt.maps.client.geom.Size;
import com.google.gwt.maps.client.overlay.Icon;
import com.google.gwt.maps.client.overlay.Marker;
import com.google.gwt.maps.client.overlay.MarkerOptions;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.FormPanel.SubmitEvent;
import com.google.gwt.user.client.ui.FormPanel.SubmitHandler;

public class GooglePopup extends DialogBox {

	private static LatLng gopoint = LatLng.newInstance(13.0810, 80.2740);

	private Geocoder geocoder;

	private static final TextBox latLabel = new TextBox();
	private static final TextBox lngLabel = new TextBox();;

	private MapWidget map;
	private HorizontalPanel horiz = new HorizontalPanel();;

	public GooglePopup(String width,String height,final String area,int left, int top, final AsyncCallback asyncCallback) {
		super(false);
		super.setAutoHideEnabled(true);
		super.setPopupPosition(left, top);
		Panel panel = new FlowPanel();
		final FormPanel form = new FormPanel();
		form.setAction("#");

		Panel formElements = new FlowPanel();
		formElements.add(horiz);

		Button submit = new Button("Find Again!");
		submit.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				form.submit();
			}
		});

		// formElements.add(submit);
		form.add(formElements);
		form.addSubmitHandler(new SubmitHandler() {
			public void onSubmit(SubmitEvent event) {
				showAddress(area);
				event.cancel();
			}
		});
		panel.add(form);

		map = new MapWidget(gopoint, 13);
		map.setScrollWheelZoomEnabled(true);
		String titleLabel = "<HTML> <HEAD> </HEAD> <BODY>  <P class='gwt-warning-label-red'> &nbsp;</span>" + "Google Map" + " </BODY></HTML>";
		this.setHTML(titleLabel);
		this.setAnimationEnabled(true);
		this.setGlassEnabled(true);
		this.setGlassStyleName("p33");
		
		if (width != null && width.length() > 0) {
			map.setWidth(width);
		} else {
			map.setWidth("750px");
		}
		if (height != null && height.length() > 0) {
			map.setHeight(height);

		} else {
			map.setHeight("450px");
		}
		
		panel.add(map);
		HorizontalPanel horizontalPanel = new HorizontalPanel();

		Button okButton = new Button("OK");
		okButton.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				GooglePopup.this.hide();
				if (asyncCallback != null) {
					Map map=new HashMap();
					map.put("Latitude", gopoint.getLatitude());
					map.put("Longitude", gopoint.getLongitude());
					asyncCallback.onSuccess(map);
				}

			}
		});

		Button cancelButton = new Button("Cancel");
		cancelButton.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				GooglePopup.this.hide();
				if (asyncCallback != null) {
					asyncCallback.onSuccess(null);
				}

			}
		});
		horizontalPanel.add(submit);
		horizontalPanel.add(okButton);
		horizontalPanel.add(cancelButton);
		panel.add(horizontalPanel);
		this.add(panel);
		geocoder = new Geocoder();
		showAddress(area);
	}

	public GooglePopup(final String add, final List area) {
		super(false);
		Panel panel = new FlowPanel();
		final FormPanel form = new FormPanel();
		form.setAction("#");

		Panel formElements = new FlowPanel();
		formElements.add(horiz);

		Button submit = new Button("Find Again!");
		submit.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				form.submit();
			}
		});

		formElements.add(submit);
		form.add(formElements);
		form.addSubmitHandler(new SubmitHandler() {
			public void onSubmit(SubmitEvent event) {
				showAddress(add, area);
				event.cancel();
			}
		});
		panel.add(form);

		map = new MapWidget(LatLng.newInstance(13.0810, 80.2740), 13);
		map.setSize("700px", "500px");
		map.setUIToDefault();
		panel.add(map);
		HorizontalPanel horizontalPanel = new HorizontalPanel();

		Button okButton = new Button("OK");
		okButton.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				GooglePopup.this.hide();
				AsyncCallback asyncCallback = new AsyncCallback() {

					@Override
					public void onFailure(Throwable caught) {
						Window.alert(caught.toString());

					}

					@Override
					public void onSuccess(Object result) {

					}
				};
				if (asyncCallback == null) {
					asyncCallback.onSuccess(null);
				}

			}
		});

		horizontalPanel.add(submit);
		horizontalPanel.add(okButton);
		// horizontalPanel.add(cancelButton);
		panel.add(horizontalPanel);
		this.add(panel);
		geocoder = new Geocoder();
		showAddress(add, area);

	}

	private void showAddress(String add, List area) {
		map.setUIToDefault();
		map.clearOverlays();

		Icon icon = Icon.newInstance("http://labs.google.com/ridefinder/images/mm_20_red.png");
		icon.setShadowURL("http://labs.google.com/ridefinder/images/mm_20_shadow.png");
		icon.setIconSize(Size.newInstance(12, 20));
		icon.setShadowSize(Size.newInstance(22, 20));
		icon.setIconAnchor(Point.newInstance(6, 20));
		icon.setInfoWindowAnchor(Point.newInstance(5, 1));

		LatLngBounds bounds = map.getBounds();
		LatLng southWest = bounds.getSouthWest();
		LatLng northEast = bounds.getNorthEast();
		double lngSpan = northEast.getLongitude() - southWest.getLongitude();
		double latSpan = northEast.getLatitude() - southWest.getLatitude();
		MarkerOptions options = MarkerOptions.newInstance();
		options.setIcon(icon);

		int length = area == null ? 0 : area.size();
		for (int i = 0; i < length; i++) {
			List latLngList = (List) area.get(i);
			int latLnglength = latLngList == null ? 0 : latLngList.size();
			if (latLnglength != 2) {
				throw new RuntimeException();
			} else {

				Double lan = Double.parseDouble(latLngList.get(0) + "");
				Double lng = Double.parseDouble(latLngList.get(1) + "");
				LatLng point = LatLng.newInstance(lan,  lng);

				map.addOverlay(new Marker(point, options));
			}

		}
	}

	private Panel buildLatLngPanel() {
		horiz.add(new Label("Lat:"));
		horiz.add(latLabel);
		horiz.add(new Label("Long:"));
		horiz.add(lngLabel);
		horiz.setSpacing(10);
		displayLatLng();
		return horiz;
	}

	private void displayLatLng() {
		NumberFormat fmt = NumberFormat.getFormat("#.0000000#");
		latLabel.setText((fmt.format(gopoint.getLatitude())));
		lngLabel.setText(fmt.format(gopoint.getLongitude()));
		buildLatLngPanel();
		horiz.clear();
		horiz.add(new Label("Lat:"));
		horiz.add(new Label((fmt.format(gopoint.getLatitude()))));
		horiz.add(new Label("Long:"));
		horiz.add(new Label(fmt.format(gopoint.getLongitude())));
		horiz.setSpacing(10);

	}

	private void showAddress(final String address) {
		final InfoWindow info = map.getInfoWindow();
		geocoder.getLatLng(address, new LatLngCallback() {
			public void onFailure() {
				Window.alert(address + " not found");
			}

			public void onSuccess(final LatLng point) {
				final MarkerOptions options = MarkerOptions.newInstance();
				options.setDraggable(true);

				map.setCenter(point, 13);
				map.setUIToDefault();
				map.setGoogleBarEnabled(true);
				gopoint = point;
				final Marker marker = new Marker(point, options);
				marker.addMarkerDragEndHandler(new MarkerDragEndHandler() {
					public void onDragEnd(MarkerDragEndEvent event) {
						gopoint = marker.getLatLng();
						info.open(marker, new InfoWindowContent(address + marker.getLatLng()));
					}
				});
				map.clearOverlays();
				map.addOverlay(marker);
				info.open(marker, new InfoWindowContent(address + marker.getLatLng()));
			}
		});
	}

	public static LatLng getINDIA() {
		return gopoint;
	}

	public static void setINDIA(LatLng india) {
		gopoint = india;
	}
}
